﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using XXX.api.Auth;
using XXX.Models.JWT;

namespace XXX.Common
{
   
        /// <summary>
        /// Token的帮助类
        /// </summary>
        public class TokenHelper
        {
          

            /// <summary>
            /// 颁发Token
            /// </summary>
            /// <returns></returns>
            public ResponseToken CreateToken(string username)
            {
            var claims = new[]
       {
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.Role, ""),
        };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenParameter.Secret));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwtToken = new JwtSecurityToken(TokenParameter.Issuer, TokenParameter.Audience, claims, expires: DateTime.UtcNow.AddMinutes(TokenParameter.AccessExpiration), signingCredentials: credentials);
            var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
           

            string refreshToken = CreateRefreshToken();

                //需要将两个Token 都放在缓存中

                return new ResponseToken() { Token = token, Refresh_Token = refreshToken };
            }

            /// <summary>
            /// 生成refresh_Token
            /// </summary>
            /// <returns></returns>
            public string CreateRefreshToken()
            {
                var refresh = new byte[32];
                using (var number = RandomNumberGenerator.Create())
                {
                    number.GetBytes(refresh);
                    return Convert.ToBase64String(refresh);
                }

                //将refresh_Token存在缓存中
            }


           /// <summary>
           /// 刷新token， 这个程序有问题。刷新提示token不可以，token也没有存到缓存或者数据库
           /// </summary>
           /// <param name="username"></param>
           /// <param name="Token"></param>
           /// <param name="refresh_Token"></param>
           /// <returns></returns>
           /// <exception cref="SecurityTokenException"></exception>
            public ResponseToken Refresh(string username,string Token, string refresh_Token)
            {

           
              string key = TokenParameter.Secret;

                byte[] secBytes = Encoding.UTF8.GetBytes(key);
                var secKey = new SymmetricSecurityKey(secBytes);

                var tokenHandler = new JwtSecurityTokenHandler();
                SecurityToken validatedToken;

                // 根据过期Token获取一个SecurityToken
                var principal = tokenHandler.ValidateToken(Token, new TokenValidationParameters()
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = secKey,
                    ValidateIssuer = true,
                    ValidIssuer = TokenParameter.Issuer,
                    ValidateAudience = true,
                    ValidAudience = TokenParameter.Audience,
                    ValidateLifetime = false
                }, out validatedToken);

                var jwtToken = validatedToken as JwtSecurityToken;

                if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature, StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new SecurityTokenException("Token不合法");
                }

                //判断refresh_Token是否此用户生成的

                //生成新Token
                List<Claim> claims = new List<Claim>()
            {
                new Claim(ClaimTypes.NameIdentifier, "1"),
                new Claim(ClaimTypes.Name, username)
            };

                var jwtSecurityToken = new JwtSecurityToken(
                    claims: claims,
                    notBefore: DateTime.Now,
                    expires: DateTime.Now.AddSeconds(TokenParameter.AccessExpiration),
                    issuer: TokenParameter.Issuer,
                    audience: TokenParameter.Audience,
                    signingCredentials: new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature)
                    );

                var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
                var refreshToken = CreateRefreshToken();

                //将缓存中原来的Token和refresh_Token 删除掉，并且保存新生成的Token

                return new ResponseToken() { Token = token, Refresh_Token = refreshToken };
            }
        }
     


}
